package com.canyou.typehandler;

import com.canyou.constants.CommonConstants;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.joda.money.CurrencyUnit;
import org.joda.money.Money;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 在 Money 与 Long 之间转换的 TypeHandler，处理 CNY 人民币
 *
 * @author fy
 * @date 20/03/20 15:34
 */
public class MoneyTypeHandler extends BaseTypeHandler<Money> {

    /**
     * 处理的货币类型
     */
    private static final String CURRENCY_UNIT = CommonConstants.CURRENCY_UNIT;

    /**
     * 设置非空参数
     *
     * @param ps
     * @param i
     * @param parameter
     * @param jdbcType
     * @throws SQLException
     */
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Money parameter, JdbcType jdbcType) throws SQLException {
        ps.setLong(i, parameter.getAmountMinorLong());
    }

    /**
     * 根据列名，获取可以为空的结果
     *
     * @param rs
     * @param columnName
     * @return
     * @throws SQLException
     */
    @Override
    public Money getNullableResult(ResultSet rs, String columnName) throws SQLException {
        long result = rs.getLong(columnName);
        if (result == 0 && rs.wasNull()) {
            return null;
        }
        return parseMoney(result);
    }

    /**
     * 根据列索引，获取可以为空的结果
     *
     * @param rs
     * @param columnIndex
     * @return
     * @throws SQLException
     */
    @Override
    public Money getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        long result = rs.getLong(columnIndex);
        if (result == 0 && rs.wasNull()) {
            return null;
        }
        return parseMoney(result);
    }

    @Override
    public Money getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        long result = cs.getLong(columnIndex);
        if (result == 0 && cs.wasNull()) {
            return null;
        }
        return parseMoney(result);
    }

    /**
     * 处理 CNY 人民币
     *
     * @param value
     * @return
     */
    private Money parseMoney(Long value) {
        if (value == null) {
            return null;
        }
        return Money.of(CurrencyUnit.of(CURRENCY_UNIT), value / 100.0);
    }

}
